import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.stage.Stage;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;


public class Constants {
    static int[][] position;//拼图的位置
    static int Step=0;//记录步数
    static boolean finalInsran = false;//进入榜单标志
    static boolean finalIntran = false;
    static int finalSran = 0;//名次标志
    static int finalTran = 0;
    static Stage winerStage = new Stage();
    static int div ;
    static MediaPlayer effect;
    static MediaPlayer game;
    static MediaPlayer win;

    ImageView imageView ;//空白拼图
    int inSquenceNum[];//随机偶排列不重复数组
    ImageView imageViews[] ;//游戏拼图组
    ImageView imageViews1[] ;//完成后拼图组
    GridPane gridPane = new GridPane();//游戏布局
    GridPane gridPane1 = new GridPane();//查看图片时的布局

    Constants(Image image){
        TimeCount.time = 0;
        TimeCount.ispause = false;
        new TimeCount().start();//开始计时
        div = (300 / StartUI.level);
        position = new int[StartUI.level][StartUI.level];
        File url = new File("yidon.mp3");
        effect = new MediaPlayer(new Media(url.toURI().toString()));
        File url1 = new File("youxi.mp3");
        game = new MediaPlayer(new Media(url1.toURI().toString()));
        game.setCycleCount(MediaPlayer.INDEFINITE);
        game.setVolume(0.75);
        File url3 = new File("win.mp3");
        win = new MediaPlayer(new Media(url3.toURI().toString()));
        win.setCycleCount(MediaPlayer.INDEFINITE);
        win.setVolume(0.75);
        inSquenceNum = new int[StartUI.level * StartUI.level - 1];
        imageViews = new ImageView[StartUI.level * StartUI.level];
        imageViews1 = new ImageView[StartUI.level * StartUI.level];
        Image image1 = new Image("Puzzle/100.png");//空白拼图
        imageView = new ImageView(image1);
        imageView.setFitHeight(div);
        imageView.setFitWidth(div);
        int k = 0;
        for (int i = 0; i < StartUI.level; i++) {
            for (int j = 0; j < StartUI.level; j++) {
                imageViews[k] = new ImageView(image);
                imageViews1[k] = new ImageView(image);
                //分割图片
                imageViews1[k].setViewport(new Rectangle2D(i*div,j*div,div,div));
                imageViews[k].setViewport(new Rectangle2D(i*div,j*div,div,div));
                //添加图片鼠标事件
                imageViews[k].setOnMouseClicked(event -> {
                    new eventAction(imageView,winerStage).mouseaction.handle(event);
                });
                k++;
            }
        }
        createSquenceNum();//生成不重复的偶排列随机数组
        setGridPane();//初始化游戏布局及完成图片显示布局
    }
    //初始化获胜界面
    static void setWinerStage() {
        TextField textField = new TextField();//玩家名称输入框
        textField.setAlignment(Pos.CENTER);
        Label bank = new Label();//空白标签，控制格式
        HBox te = new HBox(textField, bank);
        VBox hBox = new VBox();
        hBox.getChildren().addAll(te);
        Button nextg = new Button("再来一局");
        nextg.setFont(Font.font("宋体", FontWeight.BOLD, 17));
        nextg.setOnAction(event -> {
            try {
                GameUI.eventaction.buttonaction.handle2(event);
                win.stop();
                winerStage.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        Label label;
        Label label1;
        //文本框entre键事件，只保留前五名玩家成绩
        textField.setOnAction(event -> {
            if (textField.getText() != null && !textField.getText().isEmpty()) {
                String tflie = null;
                String sfile = null;
                List<String> timeRangePlayer=null;
                List<String> stepRangePlayer=null;
                List<Integer> timeRange = null;
                List<Integer> stepRange=null;
                if (StartUI.range.set.get(6).compareTo("0") == 0) {
                    timeRangePlayer = StartUI.range.NtimeRangePlayer;
                    stepRangePlayer = StartUI.range.NstepRangePlayer;
                    timeRange = StartUI.range.NtimeRange;
                    stepRange = StartUI.range.NstepRange;
                    tflie = "NtimeRange.txt";
                    sfile = "NstepRange.txt";

                } else {
                    timeRangePlayer = StartUI.range.HtimeRangePlayer;
                    stepRangePlayer = StartUI.range.HstepRangePlayer;
                    timeRange = StartUI.range.HtimeRange;
                    stepRange = StartUI.range.HstepRange;
                    tflie = "HtimeRange.txt";
                    sfile = "HstepRange.txt";
                }
                //同时进入两个榜单
                if (finalInsran && finalIntran) {
                        timeRangePlayer.add(finalTran, textField.getText());
                        timeRange.add(finalTran, TimeCount.time);
                        stepRangePlayer.add(finalSran, textField.getText());
                        stepRange.add(finalSran, Step);
                    try( BufferedWriter br1 = new BufferedWriter(new FileWriter(tflie));
                         BufferedWriter br2 = new BufferedWriter(new FileWriter(sfile));)
                    {
                        for (int i = 0; i < timeRangePlayer.size() && i < 5; i++) {
                            br1.write(timeRangePlayer.get(i) + " " + timeRange.get(i));
                            br1.newLine();
                        }
                        for (int i = 0; i < stepRangePlayer.size() && i < 5; i++) {
                            br2.write(stepRangePlayer.get(i) + " " + stepRange.get(i));
                            br2.newLine();
                        }
                        br1.flush();
                        br2.flush();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                //只进入步数榜
                if (finalInsran && !finalIntran) {
                    stepRangePlayer.add(finalSran, textField.getText());
                    stepRange.add(finalTran, Step);
                    try(BufferedWriter br2 = new BufferedWriter(new FileWriter(sfile));)
                    {
                        for (int i = 0; i < stepRangePlayer.size() && i < 5; i++) {
                            br2.write(stepRangePlayer.get(i) + " " + stepRange.get(i));
                            br2.newLine();
                        }
                        br2.flush();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                //只进入时间榜
                if (!finalInsran && finalIntran) {
                    timeRangePlayer.add(finalTran, textField.getText());
                    timeRange.add(finalTran, TimeCount.time);
                    try( BufferedWriter br1 = new BufferedWriter(new FileWriter(tflie));)
                    {
                        for (int i = 0; i < timeRangePlayer.size() && i < 5; i++) {
                            br1.write(timeRangePlayer.get(i) + " " + timeRange.get(i));
                            br1.newLine();
                        }
                        br1.flush();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                win.stop();
                winerStage.close();
                try {
                    GameUI.eventaction.buttonaction.handle2(event);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        if (finalInsran && finalIntran) {
            label = new Label("恭喜你刷新双榜成绩");
            label1 = new Label("   请留下你的名字");
            label.setFont(Font.font("宋体", FontWeight.BOLD, 17));
            label1.setFont(Font.font("宋体", FontWeight.BOLD, 17));
            VBox vBox = new VBox(label, label1, hBox);
            vBox.setSpacing(10);
            vBox.setPadding(new Insets(20, 0, 0, 20));
            ImageView back = new ImageView(StartUI.background);
            back.setOpacity(0.5);
            StackPane stackPane = new StackPane(back, vBox);
            Scene scene = new Scene(stackPane, 200, 200);
            winerStage.setScene(scene);
        }
        if (finalInsran&& !finalIntran) {
            label = new Label("恭喜你刷新步数排行榜");
            label1 = new Label("    请留下你的名字");
            label.setFont(Font.font("宋体", FontWeight.BOLD, 17));
            label1.setFont(Font.font("宋体", FontWeight.BOLD, 17));
            VBox vBox = new VBox(label, label1, hBox);
            vBox.setSpacing(10);
            vBox.setPadding(new Insets(20, 0, 0, 20));
            ImageView back = new ImageView(StartUI.background);
            back.setOpacity(0.5);
            StackPane stackPane = new StackPane(back, vBox);
            Scene scene = new Scene(stackPane, 200, 200);
            winerStage.setScene(scene);
        }
        if (!finalInsran && finalIntran) {
            label = new Label("恭喜你刷新时间排行榜");
            label1 = new Label("    请留下你的名字");
            label.setFont(Font.font("宋体", FontWeight.BOLD, 17));
            label1.setFont(Font.font("宋体", FontWeight.BOLD, 17));
            VBox vBox = new VBox(label, label1, hBox);
            vBox.setSpacing(10);
            vBox.setPadding(new Insets(20, 0, 0, 20));
            ImageView back = new ImageView(StartUI.background);
            back.setOpacity(0.5);
            StackPane stackPane = new StackPane(back, vBox);
            Scene scene = new Scene(stackPane, 200, 200);
            winerStage.setScene(scene);
        }
        if (!finalInsran && !finalIntran) {
            label = new Label("    恭喜你，成功了！");
            label.setFont(Font.font("宋体", FontWeight.BOLD, 17));
            HBox hBox1 = new HBox(nextg);
            hBox1.setPadding(new Insets(0, 0, 0, 30));
            VBox vBox = new VBox(label, hBox1);
            vBox.setSpacing(30);
            vBox.setPadding(new Insets(30, 0, 0, 20));
            ImageView back = new ImageView(StartUI.background);
            back.setOpacity(0.5);
            StackPane stackPane = new StackPane(back, vBox);
            Scene scene = new Scene(stackPane, 200, 150);
            winerStage.setScene(scene);
        }
    }
    //初始化布局
    void setGridPane() {
        int m=0;
        //记录拼图的位置
        go:for (int i = 0; i < StartUI.level; i++) {
            for (int j = 0; j < StartUI.level; j++) {
                position[i][j] = inSquenceNum[m];
                m++;
                if (m == (StartUI.level*StartUI.level-1)) {
                    break go;
                }
            }
        }
        position[StartUI.level-1][StartUI.level-1] = StartUI.level*StartUI.level-1;
        m=0;
        for (int i = 0; i < StartUI.level; i++) {
            for (int j = 0; j < StartUI.level; j++) {
                gridPane1.add(imageViews1[m],i,j);
                if (m==StartUI.level*StartUI.level-1) {
                    gridPane.add(imageView, StartUI.level-1, StartUI.level-1);
                    return;
                }
                gridPane.add(imageViews[inSquenceNum[m]], j, i);
                m++;
            }
        }
    }
    //生成随机数
    void createSquenceNum() {
        for (int i = 0; i < StartUI.level*StartUI.level-1; i++) {
            inSquenceNum[i] = -1;
        }
        boolean go = true;
        int i=0;
        int m;
        //生成StartUI.level*StartUI.level-1个不重复随机数
        while (go){
            m = (int) ((Math.random() * StartUI.level*StartUI.level)-1);
            if (!isContent(inSquenceNum, m)) {
                inSquenceNum[i] = m;
                i++;
                if (i == StartUI.level*StartUI.level-1) {
                    go = false;
                }
            }
        }
        //判断是否可拼，不可即交换其中两块拼图位置
        if ((!isEvenNum(inSquenceNum))&&(StartUI.range.set.get(6).compareTo("0") == 0)) {
            m=(int)(Math.random()*(StartUI.level*StartUI.level-1));
            if (m % 2 == 0) {
                int temp = inSquenceNum[m];
                inSquenceNum[m] = inSquenceNum[m + 1];
                inSquenceNum[m + 1] = temp;
            } else {
                int temp = inSquenceNum[m];
                inSquenceNum[m] = inSquenceNum[m - 1];
                inSquenceNum[m - 1] = temp;
            }
        }
        if ((isEvenNum(inSquenceNum))&&(StartUI.range.set.get(6).compareTo("0") != 0)) {
            m=(int)(Math.random()*(StartUI.level*StartUI.level-2));
            if (m % 2 == 0) {
                int temp = inSquenceNum[m];
                inSquenceNum[m] = inSquenceNum[m + 1];
                inSquenceNum[m + 1] = temp;
            } else {
                int temp = inSquenceNum[m];
                inSquenceNum[m] = inSquenceNum[m - 1];
                inSquenceNum[m - 1] = temp;
            }
        }
    }
    //判断是否重复
    boolean isContent(int[] inSquenceNum, int n) {
        for (int i = 0; i < StartUI.level*StartUI.level-1; i++) {
            if (inSquenceNum[i] == n) {
                return true;
            }
        }
        return false;
    }
    //判断是否可拼
    boolean isEvenNum(int []inSquenceNum) {
        int n = 0;
        for (int i = 0; i < StartUI.level*StartUI.level-2; i++) {
            for (int j = i+1; j < StartUI.level*StartUI.level-1; j++) {
                if (inSquenceNum[i] > inSquenceNum[j]) {
                    n++;
                }
            }
        }
        if (n % 2 == 0 && n != 0) {
            return false;
        } else {
            return true;
        }
    }
}
//计时器类
class TimeCount extends Thread {

    static int time = 0;//时间计数
    static boolean ispause = false;//计数开关

    public void run() {
        while (!ispause) {
            try {
                GameUI.timeShow.setText("" + time);
                Thread.sleep(1000);
                time++;
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
       }

    }

}